/**
 * @author Simon Richardson - simon@ustwo.co.uk
 */
package org.osflash.signals.natives.sets;

import org.osflash.signals.ISlot;
import asunit.asserts.Fail;
import asunit.asserts.AssertNotNull;
import asunit.asserts.AssertSame;
import asunit.asserts.AssertTrue;
import asunit.framework.IAsync;
import flash.display.Sprite;
import flash.events.Event;

class EventDispatcherSignalSetTest {

	@:meta(Inject())
	public var async : IAsync;
	var sprite : Sprite;
	var signalSet : EventDispatcherSignalSet;
	@:meta(Before())
	public function setUp() : Void {
		sprite = new Sprite();
		signalSet = new EventDispatcherSignalSet(sprite);
	}

	@:meta(After())
	public function tearDown() : Void {
		signalSet.removeAll();
		signalSet = null;
		sprite = null;
	}

	function newEmptyHandler() : Dynamic {
		return function(e : Dynamic) : Void {
		}
;
	}

	function handleEvent(event : Event) : Void {
		assertSame(sprite, event.target);
	}

	function failIfCalled(e : Event) : Void {
		fail("This event handler should not have been called.");
	}

	//////
	@:meta(Test())
	public function numListeners_should_be_zero() : Void {
		assertTrue("Number of listeners should be 0.", signalSet.numListeners == 0);
	}

	//////
	@:meta(Test())
	public function signals_should_be_not_null() : Void {
		assertNotNull("Signals should not be null.", signalSet.signals);
	}

	//////
	@:meta(Test())
	public function signals_length_should_be_empty() : Void {
		assertTrue("Signals length should be 0.", signalSet.signals.length == 0);
	}

	//////
	@:meta(Test())
	public function signals_length_should_be_zero_after_removeAll() : Void {
		signalSet.removeAll();
		assertTrue("Signals length should be 0.", signalSet.signals.length == 0);
	}

	//////
	@:meta(Test())
	public function numListeners_should_be_zero_after_removeAll() : Void {
		signalSet.removeAll();
		assertTrue("Number of listeners should be 0.", signalSet.numListeners == 0);
	}

	//////
	@:meta(Test())
	public function activate_signal_should_not_be_null() : Void {
		assertNotNull("Activate NativeSignal should not be null", signalSet.activate);
	}

	//////
	@:meta(Test())
	public function deactivate_signal_should_not_be_null() : Void {
		assertNotNull("Deactivate NativeSignal should not be null", signalSet.deactivate);
	}

	//////
	@:meta(Test())
	public function add_activate_then_EventDispatcher_dispatch_should_call_signal_listener() : Void {
		signalSet.activate.add(async.add(handleEvent));
		sprite.dispatchEvent(new Event(Event.ACTIVATE));
	}

	//////
	@:meta(Test())
	public function add_deactivate_then_EventDispatcher_dispatch_should_call_signal_listener() : Void {
		signalSet.deactivate.add(async.add(handleEvent));
		sprite.dispatchEvent(new Event(Event.DEACTIVATE));
	}

	//////
	@:meta(Test())
	public function add_activate_then_pause_and_dispatch_should_not_call_signal_listener() : Void {
		var slot : ISlot = signalSet.activate.add(failIfCalled);
		slot.enabled = false;
		sprite.dispatchEvent(new Event(Event.ACTIVATE));
	}

	//////
	@:meta(Test())
	public function add_deactivate_then_pause_and_dispatch_should_not_call_signal_listener() : Void {
		var slot : ISlot = signalSet.deactivate.add(failIfCalled);
		slot.enabled = false;
		sprite.dispatchEvent(new Event(Event.DEACTIVATE));
	}

	//////
	@:meta(Test())
	public function add_activate_then_numListeners_should_be_one() : Void {
		signalSet.activate.add(handleEvent);
		assertTrue("Number of listeners should be 1", signalSet.numListeners == 1);
	}

	//////
	@:meta(Test())
	public function add_deactivate_then_numListeners_should_be_one() : Void {
		signalSet.deactivate.add(handleEvent);
		assertTrue("Number of listeners should be 1", signalSet.numListeners == 1);
	}

	//////
	@:meta(Test())
	public function add_too_both_signals_then_numListeners_should_be_two() : Void {
		signalSet.activate.add(handleEvent);
		signalSet.deactivate.add(handleEvent);
		assertTrue("Number of listeners should be 2", signalSet.numListeners == 2);
	}

	@:meta(Test())
	public function add_too_both_signals_then_remove_activate_numListeners_should_be_one() : Void {
		signalSet.activate.add(handleEvent);
		signalSet.deactivate.add(handleEvent);
		signalSet.activate.removeAll();
		assertTrue("Number of listeners should be 1", signalSet.numListeners == 1);
	}

	@:meta(Test())
	public function add_too_both_signals_then_remove_deactivate_numListeners_should_be_one() : Void {
		signalSet.activate.add(handleEvent);
		signalSet.deactivate.add(handleEvent);
		signalSet.deactivate.removeAll();
		assertTrue("Number of listeners should be 1", signalSet.numListeners == 1);
	}

	@:meta(Test())
	public function add_too_both_signals_then_removeAll_numListeners_should_be_zero() : Void {
		signalSet.activate.add(handleEvent);
		signalSet.deactivate.add(handleEvent);
		signalSet.removeAll();
		assertTrue("Number of listeners should be 0", signalSet.numListeners == 0);
	}

}

